#include "muduo/proto/codec.h"
#include "muduo/proto/dispatcher.h"
#include "muduo/base/Logging.h"
#include "muduo/base/Mutex.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/TcpServer.h"

#include "request.pb.h"
#include <iostream>
#include<functional>
#include<unordered_map>
using namespace std;

class Server
{
   public:
          typedef std::shared_ptr<google::protobuf::Message> MessagePtr;
          typedef std::shared_ptr<ljh::TranslateRequest> TranslateRequestPtr;
          typedef std::shared_ptr<ljh::TranslateResponse> TranslateResponsePtr;
          typedef std::shared_ptr<ljh::AddRequest> AddRequestPtr;
          typedef std::shared_ptr<ljh::AddResponse> AddResponsePtr;
         Server(int port):_server(&_baseloop,muduo::net::InetAddress("0.0.0.0",port),"Server",muduo::net::TcpServer::kReusePort),
          _dispatcher(std::bind(&Server::onUnkownMessage,this,std::placeholders::_1,
               std::placeholders::_2,std::placeholders::_3)),
          _codec(std::bind(&ProtobufDispatcher::onProtobufMessage,&_dispatcher,std::placeholders::_1,
          std::placeholders::_2,std::placeholders::_3)){
//注册业务请求处理函数
     _dispatcher.registerMessageCallback<ljh::TranslateRequest>(std::bind(&Server::onTranslate, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));  
_dispatcher.registerMessageCallback<ljh::AddRequest>(std::bind(&Server::onAdd, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
     
    _server.setMessageCallback(std::bind(&ProtobufCodec::onMessage,&_codec,std::placeholders::_1,
     std::placeholders::_2,std::placeholders::_3));
     _server.setConnectionCallback(std::bind(&Server::onConnection,this,std::placeholders::_1));
  }

 public:
 void start()
 {
   _server.start();
   _baseloop.loop();
 }

 std::string translate(const std::string& str)
  {
        std::unordered_map<std::string,std::string> dict_map={{"hello","你好"},{"apple","苹果"}};
         auto it=dict_map.find(str);
         if(it==dict_map.end())
         {
            return "不知道";
         }else{
            return it->second;
         }
        

  }
 void onTranslate(const muduo::net::TcpConnectionPtr& conn,const TranslateRequestPtr& message,muduo::Timestamp)
 {
   //1.提取message中的有效消息，翻译内容
   std::string req_msg =message->msg();
   //2.进行翻译，得到结果
   std::string rsp_msg=translate(req_msg);
   //3.组织protobuf响应
   ljh::TranslateResponse resp;
   resp.set_msg(rsp_msg);
   //4.发送响应
   _codec.send(conn,resp);

 }
 void onAdd(const muduo::net::TcpConnectionPtr& conn,const AddRequestPtr& message,muduo::Timestamp)
 {
int num1=message->num1();
int num2=message->num2();
int result=num1+num2;
ljh::AddResponse resp;
resp.set_result(result);
_codec.send(conn,resp);

 }
 void onUnkownMessage(const muduo::net::TcpConnectionPtr& conn,const MessagePtr& message,muduo::Timestamp)
 {
    LOG_INFO<<"onUnkownMessage:"<<message->GetTypeName();
    conn->shutdown();
 }
    void onConnection(const muduo::net::TcpConnectionPtr& conn)
   {
   if(conn->connected())
   {
      LOG_INFO<<"连接建立成功";
   }else
   {
       LOG_INFO<<"连接即将关闭";
   }
   }
private:
  muduo::net::EventLoop _baseloop;
  muduo::net::TcpServer _server;//服务器对象
  ProtobufDispatcher _dispatcher;//请求分发器对象--要向其中注册表请求处理函数
  ProtobufCodec _codec;//protobuf协议处理器---针对收到的数据进行protobuf协议处理
}; 
  int main()
{
  Server server(8085);
  server.start();
return 0;


}
